package main

import (
	"context"
	"database/sql"
	// "database/sql"
	"fmt"
	"log"
	"net"
	"time"

	"grpc-jwt-yonghurenzheng/jwt_grpc/config"   // 复用数据库配置
	"grpc-jwt-yonghurenzheng/jwt_grpc/models"   // 复用用户模型
	pb "grpc-jwt-yonghurenzheng/jwt_grpc/proto" // 导入生成的 protos

	"github.com/golang-jwt/jwt/v4"
	"golang.org/x/crypto/bcrypt"
	"google.golang.org/grpc"
)

// authServer 结构体实现了 AuthServiceServer 接口
type authServer struct {
	pb.UnimplementedAuthServiceServer // 必须嵌入，用于向前兼容
}

// Register 实现 gRPC 注册方法
func (s *authServer) Register(ctx context.Context, req *pb.RegisterRequest) (*pb.RegisterResponse, error) {

	var existsID int64
	err := config.DB.QueryRow("SELECT id FROM users WHERE username = ?", req.Username).Scan(&existsID)
	if err == nil {
		// 查到了用户，说明用户名已存在
		return nil, fmt.Errorf("用户名已存在")
	}
	if err != sql.ErrNoRows {
		// 除了“未找到”，其他错误要返回
		return nil, fmt.Errorf("数据库查询失败: %v", err)
	}

	hashed, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
	if err != nil {
		return nil,fmt.Errorf("密码加密失败: %v", err) 
	}

	res, err := config.DB.Exec("INSERT INTO users (username, password, email) VALUES (?, ?, ?)",
		req.Username, string(hashed), req.Email)
	if err != nil {
		return nil, fmt.Errorf("注册失败: %v", err)
	}

	id, _ := res.LastInsertId()
	return &pb.RegisterResponse{Message: "注册成功", UserId: id}, nil
}

// Claims for JWT
type Claims struct {
	UserID   int64  `json:"user_id"`
	Username string `json:"username"`
	jwt.RegisteredClaims
}

// Login 实现 gRPC 登录方法
func (s *authServer) Login(ctx context.Context, req *pb.LoginRequest) (*pb.LoginResponse, error) {
	var user models.User
	var hashedPwd string
	err := config.DB.QueryRow("SELECT id, username, password FROM users WHERE username = ?", req.Username).
		Scan(&user.ID, &user.Username, &hashedPwd)
	if err != nil {
		return nil, fmt.Errorf("用户不存在或查询失败")
	}

	if err := bcrypt.CompareHashAndPassword([]byte(hashedPwd), []byte(req.Password)); err != nil {
		return nil, fmt.Errorf("密码错误")
	}

	expirationTime := time.Now().Add(24 * time.Hour)
	claims := &Claims{
		UserID:   user.ID,
		Username: user.Username,
		RegisteredClaims: jwt.RegisteredClaims{ExpiresAt: jwt.NewNumericDate(expirationTime)},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	tokenString, err := token.SignedString(config.JWTKey) // 复用 config 中的 JWTKey
	if err != nil {
		return nil, fmt.Errorf("生成 Token 失败")
	}

	return &pb.LoginResponse{Token: tokenString}, nil
}

func main() {
	config.InitDB()
	lis, err := net.Listen("tcp", ":50051") // gRPC 服务端口
	if err != nil {
		log.Fatalf("无法监听端口: %v", err)
	}

	s := grpc.NewServer()
	pb.RegisterAuthServiceServer(s, &authServer{})

	fmt.Println("🚀 Auth gRPC Service 启动于 :50051")
	if err := s.Serve(lis); err != nil {
		log.Fatalf("gRPC 服务启动失败: %v", err)
	}
}